package com.example.java.designpattern;

import com.example.java.designpattern.bridge.BridgeDivisor;
import com.example.java.designpattern.bridge.ConcreteBridgeDivisor;
import com.example.java.designpattern.bridge.ConcreteImplementor;
import com.example.java.designpattern.bridge.Implementor;
import com.example.java.designpattern.builder.CompositeDivisorBuilder;
import com.example.java.designpattern.builder.DelegateDivisorBuilder;
import com.example.java.designpattern.builder.RespChainDivisorBuilder;
import com.example.java.designpattern.singleton.DCLLazySingleton;

import java.util.Set;

/**
 * @author zengty
 * @apiNote 模拟客户端
 * @date 2024/8/29
 * @project study
 */
public class Client {

    private static final Divisor CONCRETE_DIVISOR_1 = new Divisor() {
        @Override
        public void divide(String target) {
            System.out.println("Divisor1: " + target);
        }

        @Override
        public boolean isSupport(String target) {
            return target.equals("Divisor1");
        }
    };

    private static final Divisor CONCRETE_DIVISOR_2 = new Divisor() {
        @Override
        public void divide(String target) {
            System.out.println("Divisor2: " + target);
        }

        @Override
        public boolean isSupport(String target) {
            return target.equals("Divisor2");
        }
    };

    private static final Divisor CONCRETE_DIVISOR_3 = new Divisor() {
        @Override
        public void divide(String target) {
            System.out.println("Divisor3: " + target);
        }

        @Override
        public boolean isSupport(String target) {
            return true;
        }
    };



    public static void composite(){
        Divisor divisor = CompositeDivisorBuilder.withDivisors(Set.of(CONCRETE_DIVISOR_1, CONCRETE_DIVISOR_2, CONCRETE_DIVISOR_3))
                .build();
        divisor.divide("Divisor1");
    }

    public static void delegate(){
        Divisor divisor = DelegateDivisorBuilder.withDivisors(Set.of(CONCRETE_DIVISOR_1, CONCRETE_DIVISOR_2, CONCRETE_DIVISOR_3))
                .build();
        divisor.divide("Divisor2");
    }

    public static void decorate(){
        Divisor decorate1 = new DecorateDivisor(CONCRETE_DIVISOR_1) {
            @Override
            public void divide(String s) {
                System.out.println("Decorate1: " + s);
            }
        };

        Divisor decorate2 = new DecorateDivisor(decorate1) {
            @Override
            public void divide(String s) {
                System.out.println("Decorate2: " + s);
            }
        };
        decorate1.divide("Decorate3");
    }

    public static void proxy(){
        Divisor proxy = new ProxyDivisor(CONCRETE_DIVISOR_1);
        proxy.divide("Divisor2");
    }

    public static void respChain(){
        Divisor divisorChain = RespChainDivisorBuilder.withDivisors(Set.of(CONCRETE_DIVISOR_1, CONCRETE_DIVISOR_2, CONCRETE_DIVISOR_3))
                .build();
        divisorChain.divide("Divisor3");
    }

    public static void singleton(){
        Divisor divisor = DCLLazySingleton.getInstance();
        divisor.divide("Div");
    }

    public static void templateMethod(){
        Divisor divisor = new TemplateMethodDivisor() {
            @Override
            protected void divide2(String s) {
                System.out.println("Div2: " + s);
            }

            @Override
            protected void divide1(String s) {
                System.out.println("Div1: " + s);
            }

            @Override
            protected boolean isOk(String s) {
                return true;
            }
        };

        divisor.divide("Divisor2");
    }

    public static void bridge(){
        BridgeDivisor bridgeDivisor = new ConcreteBridgeDivisor();
        Implementor implementor = new ConcreteImplementor();
        bridgeDivisor.setImplementor(implementor);
        bridgeDivisor.divide("Divisor2");
    }

    public static void main(String[] args) {
        composite();
        decorate();
        proxy();
        respChain();
        singleton();
        templateMethod();
        decorate();
        bridge();
    }
}
